package org.mozhu.mysql.learning.hitcounter;

import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HitCounterTester {
    private HitCounterClient hitCounterClient;
    private int count; // count per threads
    private int threads;
    private String name;

    public HitCounterTester(HitCounterClient hitCounterClient, String name, int count, int threads) {
        this.hitCounterClient = hitCounterClient;
        this.name = name;
        this.count = count;
        this.threads = threads;
    }

    public int getTotalCount() {
        return count * threads;
    }

    public void test() {
        StopWatch sw = new StopWatch();
        sw.start(name);
        hitCounterClient.reset();

        ExecutorService executorService = Executors.newFixedThreadPool(threads);
        List<Callable<Void>> tasks = new ArrayList<>();
        int totalCount = getTotalCount();
        for (int i = 0; i < totalCount; i++) {
            tasks.add(() -> {
                hitCounterClient.increase();
                return null;
            });
        }

        try {
            executorService.invokeAll(tasks);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        int result = hitCounterClient.count();
        sw.stop();
        System.out.println(sw.prettyPrint());

        System.out.println(String.format("Total ms: %s, Expected count: %s, Actual count: %s, Match: %s", sw.getTotalTimeMillis(), totalCount, result, totalCount == result));

        executorService.shutdown();
    }
}
